<?php

use app\models\Download;
use app\models\Project;
use app\models\Upload;
//这个文件里全是工具函数

function p($var){  //当需要输出结果,不中断的情况用P函数
    echo '<pre>';
    //print_r($var);
    var_dump($var);  //更优秀的输出方式
    echo '</pre>';
}


function dd($var){ //当需要输出,并中断后续函数的时候用dd函数
    echo '<pre>';
    //print_r($var);
    var_dump($var);  //更优秀的输出方式
    echo '</pre>';
    die;
}

//define("base_css_url", "../../web/css/base/");  //定义变量,这是公共css文件放置位置

//获取文件信息的方法
//        $path_parts = pathinfo($zipName);
//        $zipfiledir=$path_parts['dirname'];
//        $zipbasename=$path_parts['basename'];
//        $zipfilename=$path_parts['filename'];
//        p($zipfiledir);
//        //p($zipbasename);
//        //dd($zipfilename);

function rmdirr($dirname) //递归删除目录的程序
{
    // Sanity check
    if (!file_exists($dirname)) {
        return false;
    }
    // Simple delete for a file
    if (is_file($dirname) || is_link($dirname)) {
        return unlink($dirname);
    }
    // Loop through the folder
    $dir = dir($dirname);
    while (false !== $entry = $dir->read()) {
        // Skip pointers
        if ($entry == '.' || $entry == '..') {
            continue;
        }
        // Recurse
        rmdirr($dirname . DIRECTORY_SEPARATOR . $entry);
    }
    // Clean up
    $dir->close();
    return rmdir($dirname);
}

function deldir($path){
    //如果是目录则继续
    if(is_dir($path)){
        //扫描一个文件夹内的所有文件夹和文件并返回数组
        $p = scandir($path);
        //如果 $p 中有两个以上的元素则说明当前 $path 不为空
        if(count($p)>2){
            foreach($p as $val){
                //排除目录中的.和..
                if($val !="." && $val !=".."){
                    //如果是目录则递归子目录，继续操作
                    if(is_dir($path.$val)){
                        //子目录中操作删除文件夹和文件
                        deldir($path.$val.'/');
                    }else{
                        //如果是文件直接删除
                        unlink($path.$val);
                    }
                }
            }
        }
    }
    //删除目录
    return rmdir($path);
}


function postFile($url,$postData) { //当post文件时需要用这个函数
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
    curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)"); // 模拟用户使用的浏览器
    curl_setopt($curl, CURLOPT_POST, true); // 发送一个常规的Post请求
    curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); // Post提交的数据包
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
    curl_setopt($curl, CURLOPT_HEADER, false); // 显示返回的Header区域内容
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回

    $result = curl_exec($curl); // 执行操作
    return $result;

}

//教程:https://blog.csdn.net/qq_29238009/article/details/77982145
class zipa{
    function zip($dir_path,$zipName,$task){//task是压缩任务数据库对象,因为要实时反馈压缩进度,因此要有个数据库对象
        $relationArr = [$dir_path=>[
            'originName'=>$dir_path,
            'is_dir' => true,
            'children'=>[]
        ]];
        $this->modifiyFileName($dir_path,$relationArr[$dir_path]['children']);
        $zip = new ZipArchive();
        $zip->open($zipName,ZipArchive::CREATE);
        $this->zipDir(array_keys($relationArr)[0],'',$zip,array_values($relationArr)[0]['children'],$task);
        $zip->close();
        while (!file_exists($zipName)){//什么情况下为true,为true就说明文件不存在,不存在就,不能删
            sleep(1);
        }
        rmdirr($dir_path);
        return true;
    }

    function zipDir($real_path,$zip_path,&$zip,$relationArr,$task){
        $sub_zip_path = empty($zip_path)?'':$zip_path.'/';
        if (is_dir($real_path)){
            foreach($relationArr as $k=>$v){
                if($v['is_dir']){  //是文件夹
                    $zip->addEmptyDir($sub_zip_path.$v['originName']);
                    $this->zipDir($real_path.'/'.$k,$sub_zip_path.$v['originName'],$zip,$v['children'],$task);
                }else{ //不是文件夹
                    $zip->addFile($real_path.'/'.$k,$sub_zip_path.$k);
                    $zip->deleteName($sub_zip_path.$v['originName']);
                    $zip->renameName($sub_zip_path.$k,$sub_zip_path.$v['originName']);

                    $task->zip_percentage++;
                    $task->save();
                }
            }
        }
    }
    function modifiyFileName($path,&$relationArr){
        if(!is_dir($path) || !is_array($relationArr)){
            return false;
        }
        if($dh = opendir($path)){
            $count = 0;
            while (($file = readdir($dh)) !== false){
                if(in_array($file,['.','..',null])) continue; //无效文件，重来
                if(is_dir($path.'/'.$file)){
                    //$newName = md5(rand(0,99999).rand(0,99999).rand(0,99999).microtime().'dir'.$count);
                    $newName = md5('dir'.$count);
                    //p($file);
                    //p($newName);
                    $relationArr[$newName] = [
                        'originName' => iconv('GBK','UTF-8',$file),
                        'is_dir' => true,
                        'children' => []
                    ];
                    rename($path.'/'.$file, $path.'/'.$newName);
                    //rename($path.'/'.$newName,$path.'/'.$file);
                    $this->modifiyFileName($path.'/'.$newName,$relationArr[$newName]['children']);
                    $count++;
                }else{
                    $extension = strrchr($file,'.');
                    //$newName = md5(rand(0,99999).rand(0,99999).rand(0,99999).microtime().'file'.$count);
                    $newName = md5('file'.$count);
                    $relationArr[$newName.$extension] = [
                        'originName' => iconv('GBK','UTF-8',$file),
                        'is_dir' => false,
                        'children' => []
                    ];
                    rename($path.'/'.$file, $path.'/'.$newName.$extension);
                    $count++;
                }
            }
        }
    }
    function restoreFileName($path,$relationArr){
        foreach($relationArr as $k=>$v){
            //dd($path.'/'.$v['originName']);
            //dd($path.'/'.$k);
            if(!empty($v['children'])){
                $this->restoreFileName($path.'/'.$k,$v['children']);
                rename($path.'/'.$k,iconv('UTF-8','GBK',$path.'/'.$v['originName']));
                //rename("uploads/download/1600284521/4.0storage2/fa1161f8ad354416d5dd1e2d2672f22a","uploads/download/1600284521/4.0storage2/10");
                //rename($path.'/'.$k,$path.'/'.$v['originName']);
            }else{
                rename($path.'/'.$k,iconv('UTF-8','GBK',$path.'/'.$v['originName']));
                //rename($path.'/'.$k,$path.'/'.$v['originName']);
            }
        }
    }
}

class zipb{
    //这个类很好,只是不能返回压缩进度,这不好
    //它是先要先收集要压缩的目录,之后再对目录进行压缩,这对于我预先已经知道有哪些文件了的业务,是多此一举.
    //我预先知道有哪些文件,也知道文件都在哪里,我不需要先收集
    //我只需要把特定的文件压入压缩包即可
    //为什么,这个类不能返回进度?
    //因为zip类是先收集压缩信息,直到close时,才开始压缩,这样你就不能按照它收集了哪些信息的进度作为压缩的进度,而压缩的进度有完全没有反馈.所以我说这个类不能返回压缩进度.
    //所以,这个类留在这里吧,以后万一有业务需要用,就直接用吧
    //另外提醒一下:原目录压缩完,就直接删了
    /**
     * 总接口
     * @param $dir_path 需要压缩的目录地址（绝对路径）
     * @param $zipName 需要生成的zip文件名（绝对路径）
     */
    function zip($dir_path,$zipName){
        $relationArr = [$dir_path=>[
            'originName'=>$dir_path,
            'is_dir' => true,
            'children'=>[]
        ]];
        $this->modifiyFileName($dir_path,$relationArr[$dir_path]['children']);
        $zip = new ZipArchive();
        $zip->open($zipName,ZipArchive::CREATE);
        $this->zipDir(array_keys($relationArr)[0],'',$zip,array_values($relationArr)[0]['children']);
        $zip->close();
        rmdirr($dir_path);
        //$this->restoreFileName(array_keys($relationArr)[0],array_values($relationArr)[0]['children']);
    }

    /**
     * 递归添加文件进入zip
     * @param $real_path 在需要压缩的本地的目录
     * @param $zip_path zip里面的相对目录
     * @param $zip ZipArchive对象
     * @param $relationArr 目录的命名关系
     */
    function zipDir($real_path,$zip_path,&$zip,$relationArr){
        $sub_zip_path = empty($zip_path)?'':$zip_path.'\\';
        if (is_dir($real_path)){
            foreach($relationArr as $k=>$v){
                if($v['is_dir']){  //是文件夹
                    $zip->addEmptyDir($sub_zip_path.$v['originName']);
                    $this->zipDir($real_path.'\\'.$k,$sub_zip_path.$v['originName'],$zip,$v['children']);
                }else{ //不是文件夹
                    $zip->addFile($real_path.'\\'.$k,$sub_zip_path.$k);
                    $zip->deleteName($sub_zip_path.$v['originName']);
                    $zip->renameName($sub_zip_path.$k,$sub_zip_path.$v['originName']);
                }
            }
        }
    }

    /**
     * 递归将目录的文件名更改为随机不重复编号，然后保存原名和编号关系
     * @param $path 本地目录地址
     * @param $relationArr 关系数组
     * @return bool
     */
    function modifiyFileName($path,&$relationArr){
        if(!is_dir($path) || !is_array($relationArr)){
            return false;
        }
        if($dh = opendir($path)){
            $count = 0;
            while (($file = readdir($dh)) !== false){
                if(in_array($file,['.','..',null])) continue; //无效文件，重来
                if(is_dir($path.'\\'.$file)){
                    $newName = md5(rand(0,99999).rand(0,99999).rand(0,99999).microtime().'dir'.$count);
                    $relationArr[$newName] = [
                        'originName' => iconv('GBK','UTF-8',$file),
                        'is_dir' => true,
                        'children' => []
                    ];
                    rename($path.'\\'.$file, $path.'\\'.$newName);
                    $this->modifiyFileName($path.'\\'.$newName,$relationArr[$newName]['children']);
                    $count++;
                }
                else{
                    $extension = strchr($file,'.');
                    $newName = md5(rand(0,99999).rand(0,99999).rand(0,99999).microtime().'file'.$count);
                    $relationArr[$newName.$extension] = [
                        'originName' => iconv('GBK','UTF-8',$file),
                        'is_dir' => false,
                        'children' => []
                    ];
                    rename($path.'\\'.$file, $path.'\\'.$newName.$extension);
                    $count++;
                }
            }
        }
    }

    /**
     * 根据关系数组，将本地目录的文件名称还原成原文件名
     * @param $path 本地目录地址
     * @param $relationArr 关系数组
     */
    function restoreFileName($path,$relationArr){
        foreach($relationArr as $k=>$v){
            if(!empty($v['children'])){
                $this->restoreFileName($path.'\\'.$k,$v['children']);
                rename($path.'\\'.$k,iconv('UTF-8','GBK',$path.'\\'.$v['originName']));
            }else{
                rename($path.'\\'.$k,iconv('UTF-8','GBK',$path.'\\'.$v['originName']));
            }
        }
    }
}

function echoFileSize($size){
    if($size<1000){
        return $size.' B';
    }elseif($size<1000000){
        return round($size/1000,0).' K';
    }elseif($size<1000000000){
        return round($size/1000000,0).' M';
    }elseif($size<1000000000000){
        return round($size/1000000000,2).' G';
    }elseif($size<1000000000000000){
        return round($size/1000000000000,2).' T';
    }
}

function zipNow($uploads,$zipname,$taskNowTotalSize,$task){//需要压缩的目标数组,压缩后的结果,需要压缩的全部大小,此次任务的数据库对象
    if($uploads){
        $task->filecount=count($uploads);
        $filesize=0;
        foreach($uploads as $upload){
            $filesize=$filesize+$upload->size;
        }
        $task->filesize=$filesize;
        $task->save();

        $i=1;

        foreach($uploads as $upload){
            $i++;
            $zip = new \ZipArchive();

            //file_exists($zipname)?$zip->open($zipname):$zip->open($zipname,\ZipArchive::CREATE);

            if(file_exists($zipname)){
                $zip->open($zipname);
            }else{
                $zip->open($zipname,\ZipArchive::CREATE);

            }

            $project=Project::find()->where(['id'=>$upload->projectid])->one();

            $zip->addFile($upload->filepath,$project->name.'/'.$upload->sourcepath);
            $zip->close();

            //尝试获取亚完这个文件,完成总大小的百分比
            $taskNowTotalSize=$taskNowTotalSize-$upload->size;
            //p($taskNowTotalSize);
            //$task->zip_percentage=(1-$taskNowTotalSize/$task->filesize)*100;

            $task->zip_percentage=$i.'/'.$task->filecount;
            $task->save();
        }
        return true;
    }else{
        return false;
    }
}
function tarNow($uploads,$tarname,$taskNowTotalSize,$task,$tmpdir){//需要压缩的目标数组,压缩后的结果,需要压缩的全部大小,此次任务的数据库对象
    if($uploads){
        $task->filecount=count($uploads);
        $filesize=0;
        foreach($uploads as $upload){
            $filesize=$filesize+$upload->size;
        }
        $task->filesize=$filesize;
        $task->save();

        $i=0;
        doLog("开始收集文件,事件id:".$task->id);
        foreach($uploads as $upload){
            $i++;
            $project=Project::find()->where(['id'=>$upload->projectid])->one();
            $targetFile=$tmpdir."/".$project->name.'/'.$upload->sourcepath; //download/21321314/4.0storage/xxpt/student/class1/a.txt
            $targetdir=dirname($targetFile);//download/21321314/4.0storage/xxpt/student/class1/
            if(!file_exists($targetdir))  mkdir($targetdir,0777,true);

            //doLog($targetdir);
            doLog($upload->sourcepath);
//            if ($targetdir==$tmpdir."/".$project->name.'/"'){
//                doLog("看看这是个啥".$upload->filename);
//            }

            $copyresult=copy($upload->filepath,$tmpdir."/".$project->name.'/'.$upload->sourcepath);
            doLog($copyresult);
            //upload/46febd1e47404223e7294e51be98b32f  , download/21321314/4.0storage/xxpt/student/class1/a.txt

            $task->zip_percentage=$i.'/'.$task->filecount;
            if ($i%5==0){
                $task->save();
            }
        }
        $task->save();
        doLog("结束收集文件,事件id:".$task->id);
        //download/21321314 download/21321314.tar.gz

        $shell='tar zcvf '.$tarname.' '.$tmpdir.';rm -rf '.$tmpdir;//tar打包: tar zcvf a.tar.gz a ;rm -rf a
        doLog($shell);
        //exec($shell, $result, $status);
        $status=0;
        if($status==0){
            doLog($tarname.' create successful');
            //return $tarname.' create successful';
        }else{
            doLog($tarname.' create false');
            //return $tarname.' create false';
        }
        //return true;
    }else{
        //return false;
        doLog("没有要打包的文件:".$task->id);
    }
}

class Phdfs{//这是php操作hadoop的类,它需要系统内部有hadoop,要和这个系统部署在同一台服务器
    function mkdir($dir,$options){//创建目录
        $hadoop=Yii::$app->params['hadoop'];// 定义hadoop命令的地址
        $shell=$hadoop.' -test -e '.$dir;//判断目录是否存在
        exec($shell, $result, $status);
        if($status==0){
            return $dir.' is exists,not create';
            dd($result);
        }else{
            $shell=$hadoop.' -mkdir -p '.$dir;//创建目录
            exec($shell, $result, $status);
            if($status==0){
                return $dir.' create successful';
            }else{
                return $dir.' create false';
            }
        }
    }
    function ls($item,$options){
        $hadoop=Yii::$app->params['hadoop'];// 定义hadoop命令的地址
        $shell=$hadoop.' -test -e '.$item;//判断目录或文件是否存在
        exec($shell, $result, $status);
        if($status!=0){
            dd('不存在');
            return $item.' is not exists';

        }else{
            //dd('存在');
            $shell=$hadoop.' -test -d '.$item;//判断是不是目录
            exec($shell, $result, $status);
            if($status==0){
                $shell=$hadoop.' -ls -R '.$item;//查看目录
            }else{
                $shell=$hadoop.' -ls '.$item;//查看文件
            }
            //p($shell);

            exec($shell, $result, $status);
            if($status==0){
                //p('结果是:'.implode($result));
                return $result;
            }else{
                //p($item.' 查看失败');
                return $item.' 查看失败';
            }
        }
    }
    function put($source,$target,$options=''){
        $hadoop=Yii::$app->params['hadoop'];// 定义hadoop命令的地址
        $shell=$hadoop.' -test -e '.$target;//判断目录或文件是否存在
        exec($shell, $result, $status);
        if($status==0){//说明存在这个东西
            return '上传完毕';
            //$shell=$hadoop.' -test -d '.$target;//判断是不是目录
            //exec($shell, $result, $status);
            //if($status==0){//目标是目录
            //    //如果目录里没有这个子目录,那就是新建,否则,就是强制覆盖
            //    $shell=$hadoop.' -put -p -f '.$options.' '.$source.' '.$target;
            //    exec($shell, $result, $status);
            //    if($status==0){
            //        return '上传完毕' ;
            //    }else{
            //        return '上传失败';
            //    }
            //}else{//目标存在,并且是文件,因此要覆盖
            //    $shell=$hadoop.' -put -p -f '.$options.' '.$source.' '.$target;
            //    exec($shell, $result, $status);
            //    if($status==0){
            //        return'上传完毕';
            //    }else{
            //        return'上传失败';
            //    }
            //}
        }else{//说明不存在这个东西
            //判断目标的父目录是否存在
            $targetParent=substr($target,0,strrpos($target,"/"));//如:/uploads/46febd1e47404223e7294e51be98b32f
            // 结果是:/uploads
            $shell=$hadoop.' -test -e '.$targetParent;//判断父目录是否存在
            exec($shell, $result, $status);
            if($status==0){//父目录存在
                $shell=$hadoop.' -put -p '.$options.' '.$source.' '.$target;
                exec($shell, $result, $status);
                if($status==0){
                    return '上传完毕';
                }else{
                    return '上传失败';
                }
            }else{//父目录不存在
                $this->mkdir($targetParent,$options);//先创建父目录,再上传
                $shell=$hadoop.' -put -p '.$options.' '.$source.' '.$target;
                exec($shell, $result, $status);
                if($status==0){
                    return '上传完毕' ;
                }else{
                    return '上传失败';
                }
            }
        }
    }
    function get($source,$target){
        $hadoop=Yii::$app->params['hadoop'];// 定义hadoop命令的地址
        $shell=$hadoop.' -test -e '.$source;//判断目录或文件是否存在
        //dd($shell);
        exec($shell, $result, $status);
        if($status==0){//说明存在这个东西
            $shell=$hadoop.' -test -d '.$source;//判断是不是目录
            exec($shell, $result, $status);
            if($status==0){//目标是目录
                //这一部分其实没什么用,因为每次从hdfs下载文件都是一个一个的下载,不存在一下好多个文件的情况
                $shell=$hadoop.' -get '.$source .' ' .$target;//获取目录

                exec($shell, $result, $status);
                if($status==0){//已经拿下来了
                    return '获取成功' ;
                }else{//没拿下来
                    return '下载失败';
                }
            }else{//目标存在,并且是文件
                $shell=$hadoop.' -get '.$source .' ' .$target;//获取文件
                exec($shell, $result, $status);
                if($status==0){//已经拿下来了
                    return '获取成功' ;
                }else{//没拿下来
                    return '下载失败';
                }
            }
        }else{//说明不存在这个东西
            return '要下载的目录或文件不存在';
        }
    }
    function rm($item){
        //dd($item);
        $hadoop=Yii::$app->params['hadoop'];// 定义hadoop命令的地址
        $shell=$hadoop.' -test -e '.$item;//判断目录或文件是否存在
        exec($shell, $result, $status);
        if($status!=0){
            //return $item;
            //dd('不存在');
            return $item.' is not exists';

        }else{
            //dd('存在');

            $shell=$hadoop.' -rm -r '.$item;
            exec($shell, $result, $status);
            if($status!=0){
                return '删除失败';
            }else{
                return '删除成功';
            }
        }
    }
    function exists($item)
    {
        $hadoop = Yii::$app->params['hadoop'];// 定义hadoop命令的地址
        $shell = $hadoop . ' -test -e ' . $item;//判断目录或文件是否存在
        exec($shell, $result, $status);
        
        if ($status == 0) {
            return true;
        } else {
            return false;
        }
    }
}



function delDirAndFile( $dirName ){
    if ( $handle = opendir( "$dirName" ) ) {
        while ( false !== ( $item = readdir( $handle ) ) ) {
            if ( $item != "." && $item != ".." ) {
                if ( is_dir( "$dirName/$item" ) ) {
                    delDirAndFile( "$dirName/$item" );
                } else {
                    unlink( "$dirName/$item" );
                }
            }
        }
        closedir( $handle );
        rmdir( $dirName );
    }
}

function deleteItemArray($arrayDemo,$item){//从数组总删除某一个特定值的item
    foreach ($arrayDemo as $k=>$v){
        if($v==$item){
            unset($arrayDemo[$k]);
        }
    }
    return array_values($arrayDemo);
}
function saveTmpFileToDisk($tmp_file,$fileStorePath){
    rename($tmp_file, $fileStorePath); //把临时文件 mv 成 md5 文件
    if(\Yii::$app->params['useHdfs'] ){
        $phdfs=new \Phdfs();
        $result=$phdfs->put($fileStorePath,'/'.$fileStorePath,'$options');//上传文件到hdfs
        if(is_string($result)){
            if(strpos($result,'上传完毕')!==false){
                //往hdfs上传成功
                //return $fileStorePath;
                unlink($fileStorePath);//既然hdfs中有了,那么本地目录就必须要保留了
            }else{
                //往hdfs上传失败
                return $result;//打印失败消息
            }
        }else{
            if(count($result)==0){
                dd('结果是:空');
            }
        }
    }
}

function deleteFile($upload){
    if(\Yii::$app->params['useHdfs']){//如果用了hdfs,那就删除hdfs中的文件,即可
        $phdfs=new \phdfs();
        $phdfs->rm('/'.$upload->filepath);
    }else{//没使用hdfs, 那就要删除本地文件了
        if(file_exists($upload->filepath)){
            unlink($upload->filepath); //删除文件
        }
    }
}
function deleteOneUpload($upload){
    $filepath=$upload->filepath;
    $result=Upload::find()->where(['filepath'=>$filepath])->all();
    $isDeleteFile="";
    if(count($result)==1){//这主要是考虑到一个md5文件对应多条md5记录,有多个记录指向同一个md5文件时,不应删除文件
        deleteFile($upload);
        $isDeleteFile=true;
    }else{
        //否则,你就不应该删除文件,只删除记录就可以了
    }//文件处理完了,接下来去处理记录
    $projectid=$upload->projectid;
    $projectObj=Project::find()->where(["id"=>$projectid])->one();//项目
    if($upload->own){//你是所有者
        doLog("你是所有者");
        if($isDeleteFile){//文件已删除,你就是唯一,删记录,减total,减realtotal
            $projectObj->totalRealSize=$projectObj->totalRealSize-$upload->size;
            $projectObj->totalSize=$projectObj->totalSize-$upload->size;
            $projectObj->count=$projectObj->count-1;
            $projectObj->save();
            $upload->delete();
        }else{//文件没删除,还有用着的记录,并且你是所有者,那么你需要交出所有者身份
            doLog("没删除文件");
            $sameMd5s=Upload::find()->where(["md5"=>$upload->md5])->all();
            $sameMd5sNotIncludeThisUpload=deleteItemArray($sameMd5s,$upload);
            $sameMd5sNotIncludeThisUpload[0]->own=true;
            $sameMd5sNotIncludeThisUpload[0]->save();

            $projectObj->totalRealSize=$projectObj->totalRealSize-$upload->size;
            $projectObj->totalSize=$projectObj->totalSize-$upload->size;
            $projectObj->count=$projectObj->count-1;
            $projectObj->save();
            $upload->delete();

            if($sameMd5sNotIncludeThisUpload[0]->projectid==$upload->projectid){
                $projectObj->totalRealSize=$projectObj->totalRealSize+$upload->size;
                $projectObj->save();
            }else{
                $projectId=$sameMd5sNotIncludeThisUpload[0]->projectid;
                $needEditProject=Project::find()->where(["id"=>$projectId])->one();
                $needEditProject->totalRealSize=$needEditProject->totalRealSize+$upload->size;
                $needEditProject->save();
            }
        }
    }else{
        //你不是文件所有者,那么只需要删除这条记录,并修改项目记录即可
        $projectObj->totalSize=$projectObj->totalSize-$upload->size;
        $projectObj->count=$projectObj->count-1;
        $projectObj->save();
        $upload->delete();
    }
}
function doLog($msg){
    error_log("\n!!!!!!!!!!!!!!!!!!\n",3,\Yii::$app->params['logFile']);
    error_log( $msg,3,\Yii::$app->params['logFile']);
    error_log("\n##################\n",3,\Yii::$app->params['logFile']);
}

function saveNewFileAndSaveMysql($project,$filesizea,$tmp_file,$fileStorePath,$upload,$filename,$md5,$sourcePath,$deletetime){//存一个绝对新的文件进系统
    $project->totalRealSize=$project->totalRealSize+$filesizea;    //存了硬盘,就应该修改实际项目总大小
    $project->totalSize=$project->totalSize+$filesizea;          //管你存不存硬盘,都要增加理论文件大小
    $project->count=$project->count+1;
    $project->save();

    saveTmpFileToDisk($tmp_file,$fileStorePath);//把临时文件 mv 成 md5 文件
    $upload->filename=$filename; //这里要注意,表的字段用的不是点,而是方法的表达方式
    $upload->filepath=$fileStorePath;
    $upload->md5=$md5;
    $upload->sourcepath=$sourcePath;
    $upload->deletetime=$deletetime;
    $upload->size=$filesizea;
    $upload->projectid=$project->id;
    $upload->own=true; //true表示这个文件是第一次存入
    $upload->save(); //save() 和 insert() 都能插入
}//存一个绝对新的文件进系统

function saveExistFileAndSaveMysql($tmp_file,$project,$filesizea,$upload,$filename,$fileStorePath,$md5,$sourcePath,$deletetime){//存一个系统中已有的文件进系统
    unlink($tmp_file);

    $project->totalSize=$project->totalSize+$filesizea;          //管你存不存硬盘,都要增加理论文件大小
    $project->count=$project->count+1;
    $project->save();

    $upload->filename=$filename; //这里要注意,表的字段用的不是点,而是方法的表达方式
    $upload->filepath=$fileStorePath;
    $upload->md5=$md5;
    $upload->sourcepath=$sourcePath;
    $upload->deletetime=$deletetime;
    $upload->size=$filesizea;
    $upload->projectid=$project->id;
    $upload->own=false;
    $upload->save(); //save() 和 insert() 都能插入
}


function msectime()
{
    list($msec, $sec) = explode(' ', microtime());
    $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    return $msectime;
}